!> 3D nearest neighbor particle search (uniform distribution)
program main

    use random_module, only: randn, randu
    use nnps_module, only: wp, nnps_direct3d, nnps_octree, nnps_grid3d
    use nnpx_command_line, only: get_m_value_from_CLI
    use timer_module, only: timer, sec2hms
    use display_module, only: display
    use progress_bar_module, only: progress_bar
    implicit none
    real(wp), dimension(:, :), allocatable :: loc
    integer :: loop, i
    integer :: m
    real :: loading_factor
    type(timer) :: tmr
    type(nnps_grid3d) :: nnps_grid
    integer, pointer :: pairs(:)
    real(wp), pointer :: rdxs(:)
    real(wp) :: t1, t2, x

    call get_m_value_from_CLI(m, loading_factor)
    loop = 20
    x = (real(m)/loading_factor)**(1.0_wp/3.0_wp)/2
    allocate (loc(3, m))
    call randu(loc, -x, x)
    call display(real(m)/(x*2/1.0_wp)**3*100, 'load factor (%):', inline=.true.)
    call display(x, 'x:', inline=.true.)
    call nnps_grid%init(loc, m)

    call cpu_time(t1)
    call tmr%tic()
    do i = 1, loop
        call nnps_grid%query(1.0_wp, pairs, rdxs, m)
        ! call progress_bar(i, loop, advance=.false.)
    end do
    ! call progress_bar(loop, loop, advance=.true.)

    print *, "*** grid3d ***"
    call display(sec2hms(tmr%toc()), 'time:', inline=.true.)
    call cpu_time(t2)
    call display(t2 - t1, 'cpu_time:', inline=.true.)
    call display((t2 - t1)/loop*1000, 'cpu_time/loop (ms):', inline=.true.)
    call display(pairs, 'pairs:')
#ifdef PAUSE
    read (*, *)
#endif


end program main
!>  grid3d: 00:00:00.273
!> [vector: 474] pairs:
!>  8.080E+02,  9.400E+02,  7.000E+00, ...  7.710E+02
!>  tree3d: 00:00:33.071
!> [vector: 474] pairs:
!>  2.000E+00,  6.510E+02,  7.000E+00, ...  9.820E+02
!>  direct3d: 00:00:03.267
!> [vector: 474] pairs:
!>  2.000E+00,  6.510E+02,  7.000E+00, ...  9.820E+02
